package com.example.service.impl;

import com.example.dto.CourseSelectionDTO;
import com.example.entity.*;
import com.example.mapper.*;
import com.example.service.CourseSelectionService;
import com.example.vo.AvailableCourseVO;
import com.example.vo.StudentCourseSelectionVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class CourseSelectionServiceImpl implements CourseSelectionService {

    @Autowired
    private StudentCourseSelectionMapper studentCourseSelectionMapper;

    @Autowired
    private StudentMapper studentMapper;

    @Autowired
    private CourseMapper courseMapper;

    @Autowired
    private UserOrganizationMapper userOrganizationMapper;

    @Autowired
    private OrganizationMapper organizationMapper;

    @Override
    public List<AvailableCourseVO> getAvailableCourses(Long studentId) {
        // 获取学生信息
        Student student = studentMapper.selectById(studentId);
        if (student == null) {
            throw new RuntimeException("学生信息不存在");
        }

        // 获取学生的组织信息
        StudentOrganizationInfo studentOrgInfo = getStudentOrganizationInfo(student);

        // 获取所有开设的课程（不进行过滤）
        List<AvailableCourseVO> allCourses = studentCourseSelectionMapper.getAvailableCourses(studentId);

        // 为每个课程标记是否可以选择，但不过滤掉不匹配的课程
        return allCourses.stream()
                .map(course -> {
                    // 检查是否可以选择该课程
                    boolean canSelect = canStudentSelectCourse(studentOrgInfo, course.getCourseApplicationId());
                    // 设置一个标记字段来表示是否可选择（这里我们需要扩展VO）
                    course.setCanSelect(canSelect);
                    return course;
                })
                .collect(Collectors.toList());
    }

    @Override
    public List<StudentCourseSelectionVO> getSelectedCourses(Long studentId) {
        return studentCourseSelectionMapper.getSelectedCourses(studentId);
    }

    @Override
    @Transactional
    public void selectCourse(CourseSelectionDTO courseSelectionDTO) {
        Long studentId = courseSelectionDTO.getStudentId();
        Long courseApplicationId = courseSelectionDTO.getCourseApplicationId();

        // 检查学生是否已选择该课程
        Integer selectedCount = studentCourseSelectionMapper.checkCourseSelected(studentId, courseApplicationId);
        if (selectedCount > 0) {
            throw new RuntimeException("您已经选择了该课程");
        }

        // 检查课程是否已满员
        Integer isFull = studentCourseSelectionMapper.checkCourseFull(courseApplicationId);
        if (isFull > 0) {
            throw new RuntimeException("该课程已满员");
        }

        // 获取学生信息
        Student student = studentMapper.selectById(studentId);
        if (student == null) {
            throw new RuntimeException("学生信息不存在");
        }

        // 获取课程信息
        Course course = courseMapper.selectById(courseApplicationId);
        if (course == null) {
            throw new RuntimeException("课程信息不存在");
        }

        // 检查课程是否同一科目（课程名称相同）
        Long sameSubjectCount = studentCourseSelectionMapper.checkSameSubject(studentId, course.getCourseName());
        if (sameSubjectCount > 0) {
            throw new RuntimeException("同一科目不能选择多次");
        }

        // 检查学生是否有权限选择该课程（学院专业班级和学年学期匹配）
        StudentOrganizationInfo studentOrgInfo = getStudentOrganizationInfo(student);
        if (!canStudentSelectCourse(studentOrgInfo, courseApplicationId)) {
            throw new RuntimeException("您只能选择本学院本专业本班级教师开设的课程，且学年学期必须匹配");
        }
        
        // 检查是否存在该学生和课程的记录
        StudentCourseSelection existingRecord = studentCourseSelectionMapper.findExistingRecord(studentId, courseApplicationId);
        
        if (existingRecord != null) {
            // 如果存在记录且状态为退课(0)，则重新激活
            if (existingRecord.getStatus() == 0) {
                int result = studentCourseSelectionMapper.reactivateSelection(studentId, courseApplicationId);
                if (result == 0) {
                    throw new RuntimeException("选课失败，请重试");
                }
            } else {
                // 状态为1说明已经选课，这种情况在前面已经检查过了
                throw new RuntimeException("您已经选择了该课程");
            }
        } else {
            // 不存在记录，创建新的选课记录
            StudentCourseSelection selection = new StudentCourseSelection();
            selection.setStudentId(studentId);
            selection.setStudentNo(student.getStudentNo());
            selection.setStudentName(student.getName());
            selection.setCourseApplicationId(courseApplicationId);
            selection.setCourseName(course.getCourseName());
            selection.setTeacherId(course.getTeacherId());
            selection.setTeacherName(course.getTeacherName());
            selection.setAcademicYear(course.getAcademicYear());
            selection.setSemester(course.getSemester());
            selection.setCourseHours(course.getCourseHours());
            selection.setSelectionTime(LocalDateTime.now());
            selection.setStatus(1);
            selection.setCreateTime(LocalDateTime.now());
            selection.setUpdateTime(LocalDateTime.now());
            selection.setDeleted(0);
            
            studentCourseSelectionMapper.insert(selection);
        }
    }

    @Override
    @Transactional
    public void dropCourse(Long studentId, Long courseApplicationId) {
        // 检查学生是否已选择该课程
        Integer selectedCount = studentCourseSelectionMapper.checkCourseSelected(studentId, courseApplicationId);
        if (selectedCount == 0) {
            throw new RuntimeException("您未选择该课程");
        }

        // 更新选课记录状态为退课
        int result = studentCourseSelectionMapper.updateStatusToDrop(studentId, courseApplicationId);
        if (result == 0) {
            throw new RuntimeException("退课失败，请重试");
        }
    }

    /**
     * 获取学生的组织信息
     */
    private StudentOrganizationInfo getStudentOrganizationInfo(Student student) {
        StudentOrganizationInfo info = new StudentOrganizationInfo();
        info.setStudent(student); // 设置学生对象引用

        // 获取学生的组织信息
        List<UserOrganization> userOrganizations = userOrganizationMapper.selectByUserId(student.getUserId());
        if (userOrganizations.isEmpty()) {
            return info; // 学生没有分配组织，返回空信息
        }

        // 获取学生所属的组织ID列表
        List<Long> studentOrgIds = userOrganizations.stream()
                .map(UserOrganization::getOrganizationId)
                .collect(Collectors.toList());

        for (Long orgId : studentOrgIds) {
            Organization org = organizationMapper.selectById(orgId);
            if (org != null) {
                if (org.getOrgLevel() == 1) { // 学院
                    info.setCollegeId(org.getId());
                } else if (org.getOrgLevel() == 2) { // 专业
                    info.setMajorId(org.getId());
                    // 如果是专业，需要找到其父级学院
                    if (org.getParentId() != null && org.getParentId() != 0) {
                        Organization college = organizationMapper.selectById(org.getParentId());
                        if (college != null && college.getOrgLevel() == 1) {
                            info.setCollegeId(college.getId());
                        }
                    }
                } else if (org.getOrgLevel() == 3) { // 班级
                    info.setClassId(org.getId());
                    // 如果是班级，需要找到其专业和学院
                    if (org.getParentId() != null && org.getParentId() != 0) {
                        Organization major = organizationMapper.selectById(org.getParentId());
                        if (major != null && major.getOrgLevel() == 2) {
                            info.setMajorId(major.getId());
                            if (major.getParentId() != null && major.getParentId() != 0) {
                                Organization college = organizationMapper.selectById(major.getParentId());
                                if (college != null && college.getOrgLevel() == 1) {
                                    info.setCollegeId(college.getId());
                                }
                            }
                        }
                    }
                }
            }
        }

        return info;
    }

    /**
     * 获取教师的组织信息
     */
    private TeacherOrganizationInfo getTeacherOrganizationInfo(Long teacherId) {
        TeacherOrganizationInfo info = new TeacherOrganizationInfo();

        // 获取教师的组织信息
        List<UserOrganization> userOrganizations = userOrganizationMapper.selectByUserId(teacherId);
        if (userOrganizations.isEmpty()) {
            return info; // 教师没有分配组织，返回空信息
        }

        // 获取教师所属的组织ID列表
        List<Long> teacherOrgIds = userOrganizations.stream()
                .map(UserOrganization::getOrganizationId)
                .collect(Collectors.toList());

        for (Long orgId : teacherOrgIds) {
            Organization org = organizationMapper.selectById(orgId);
            if (org != null) {
                if (org.getOrgLevel() == 1) { // 学院
                    info.setCollegeId(org.getId());
                } else if (org.getOrgLevel() == 2) { // 专业
                    info.setMajorId(org.getId());
                    // 如果是专业，需要找到其父级学院
                    if (org.getParentId() != null && org.getParentId() != 0) {
                        Organization college = organizationMapper.selectById(org.getParentId());
                        if (college != null && college.getOrgLevel() == 1) {
                            info.setCollegeId(college.getId());
                        }
                    }
                } else if (org.getOrgLevel() == 3) { // 班级
                    info.addClassId(org.getId());
                    // 如果是班级，需要找到其专业和学院
                    if (org.getParentId() != null && org.getParentId() != 0) {
                        Organization major = organizationMapper.selectById(org.getParentId());
                        if (major != null && major.getOrgLevel() == 2) {
                            info.setMajorId(major.getId());
                            if (major.getParentId() != null && major.getParentId() != 0) {
                                Organization college = organizationMapper.selectById(major.getParentId());
                                if (college != null && college.getOrgLevel() == 1) {
                                    info.setCollegeId(college.getId());
                                }
                            }
                        }
                    }
                }
            }
        }

        return info;
    }

    /**
     * 检查学生是否可以选择该课程
     * 学生只能选择与自己同学院、同专业、同班级的教师开设的课程，且学年学期必须匹配
     */
    private boolean canStudentSelectCourse(StudentOrganizationInfo studentOrgInfo, Long courseApplicationId) {
        // 获取课程信息
        Course course = courseMapper.selectById(courseApplicationId);
        if (course == null || course.getTeacherId() == null) {
            return false;
        }

        // 检查学年学期匹配
        if (!checkAcademicYearAndSemesterMatch(studentOrgInfo.getStudent(), course)) {
            return false; // 学年学期不匹配
        }

        // 获取教师的组织信息
        TeacherOrganizationInfo teacherOrgInfo = getTeacherOrganizationInfo(course.getTeacherId());

        // 检查学院匹配
        if (studentOrgInfo.getCollegeId() == null || teacherOrgInfo.getCollegeId() == null) {
            return false; // 学生或教师没有分配学院
        }
        if (!studentOrgInfo.getCollegeId().equals(teacherOrgInfo.getCollegeId())) {
            return false; // 学院不匹配
        }

        // 检查专业匹配
        if (studentOrgInfo.getMajorId() == null || teacherOrgInfo.getMajorId() == null) {
            return false; // 学生或教师没有分配专业
        }
        if (!studentOrgInfo.getMajorId().equals(teacherOrgInfo.getMajorId())) {
            return false; // 专业不匹配
        }

        // 检查班级匹配
        if (studentOrgInfo.getClassId() == null || teacherOrgInfo.getClassIds() == null || teacherOrgInfo.getClassIds().isEmpty()) {
            return false; // 学生没有分配班级或教师没有管理任何班级
        }
        if (!teacherOrgInfo.getClassIds().contains(studentOrgInfo.getClassId())) {
            return false; // 学生的班级不在教师管理的班级列表中
        }

        return true; // 学院、专业、班级、学年学期都匹配
    }

    /**
     * 检查学年学期是否匹配
     */
    private boolean checkAcademicYearAndSemesterMatch(Student student, Course course) {
        // 检查学年匹配 - 需要从学生的学年学期信息中提取学年部分
        if (student.getCurrentYear() == null || student.getGrade() == null || course.getAcademicYear() == null) {
            return false; // 学生或课程没有设置学年信息
        }

        // 生成学生当前的学年格式（xxxx-xxxx）
        String studentAcademicYear = generateStudentAcademicYear(student.getGrade(), student.getCurrentYear());
        if (studentAcademicYear == null) {
            return false; // 学年生成失败
        }

        if (!studentAcademicYear.equals(course.getAcademicYear())) {
            return false; // 学年不匹配
        }

        // 检查学期匹配 - 这里需要将学生的当前学期数字转换为学期名称
        String studentSemester = convertSemesterNumberToName(student.getCurrentSemester());
        if (studentSemester == null || course.getSemester() == null) {
            return false; // 学生或课程没有设置学期
        }
        if (!studentSemester.equals(course.getSemester())) {
            return false; // 学期不匹配
        }

        return true; // 学年学期都匹配
    }

    /**
     * 生成学生当前的学年格式（xxxx-xxxx）
     */
    private String generateStudentAcademicYear(String grade, Integer currentYear) {
        try {
            int gradeYear = Integer.parseInt(grade);

            // 计算当前所在的学年
            int academicStartYear = gradeYear + (currentYear - 1);
            int academicEndYear = academicStartYear + 1;

            return String.format("%d-%d", academicStartYear, academicEndYear);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 将学期数字转换为学期名称
     */
    private String convertSemesterNumberToName(Integer semesterNumber) {
        if (semesterNumber == null) {
            return null;
        }
        switch (semesterNumber) {
            case 1:
                return "第一学期";
            case 2:
                return "第二学期";
            default:
                return null;
        }
    }

    /**
     * 学生组织信息
     */
    private static class StudentOrganizationInfo {
        private Long collegeId;
        private Long majorId;
        private Long classId;
        private Student student; // 添加学生对象引用

        public Long getCollegeId() {
            return collegeId;
        }

        public void setCollegeId(Long collegeId) {
            this.collegeId = collegeId;
        }

        public Long getMajorId() {
            return majorId;
        }

        public void setMajorId(Long majorId) {
            this.majorId = majorId;
        }

        public Long getClassId() {
            return classId;
        }

        public void setClassId(Long classId) {
            this.classId = classId;
        }

        public Student getStudent() {
            return student;
        }

        public void setStudent(Student student) {
            this.student = student;
        }
    }

    /**
     * 教师组织信息
     */
    private static class TeacherOrganizationInfo {
        private Long collegeId;
        private Long majorId;
        private List<Long> classIds = new java.util.ArrayList<>();

        public Long getCollegeId() {
            return collegeId;
        }

        public void setCollegeId(Long collegeId) {
            this.collegeId = collegeId;
        }

        public Long getMajorId() {
            return majorId;
        }

        public void setMajorId(Long majorId) {
            this.majorId = majorId;
        }

        public List<Long> getClassIds() {
            return classIds;
        }

        public void setClassIds(List<Long> classIds) {
            this.classIds = classIds;
        }

        public void addClassId(Long classId) {
            if (this.classIds == null) {
                this.classIds = new java.util.ArrayList<>();
            }
            this.classIds.add(classId);
        }
    }
}